iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
Kubernetes

Kubernetes學習心得分享系列 第 9 篇

Day 09:【系統】 常駐服務與靜態 Pod 部署 (DaemonSet & Static Pods)

  • 分享至 

  • xImage
  •  

前言

寫這篇想要分享的重點:
在 Kubernetes 叢集中,除了由 Control Plane 統一調度的無狀態與有狀態應用外,還有一類特殊需求:例如日誌收集器、節點監控 Agent 或 CNI 網路插件,需要在「每一個 Node」上都常駐運行。本篇將說明 DaemonSet 與 Static Pods 的設計理念、原理與應用場景。

這篇想要講什麼:

  1. DaemonSet 概念:確保全叢集(或指定節點)皆運行一份 Pod copy、遵從一套YAML 定義與版本。
  2. Static Pods 運作原理:無須通過 API Server 與 Scheduler,由 Kubelet 直接監控本機目錄管理的靜態 Pod,以及 Mirror Pod 的機制。
  3. 對比與總結:DaemonSet 與 Static Pods 在架構上的差異。

為何要寫這篇:
瞭解這兩種特殊部署方式,有助我們清楚「K8s 控制面組件(如 kube-apiserver, etcd)是如何自我啟動(Bootstrapping)的」,以及叢集該如何維護除錯。

名詞對應

  • Static Pod: 靜態 Pod
  • Control Plane: 控制面
  • Scheduler: 調度器
  • Bootstrapping: 自我啟動
  • Mirror Pod: 映象 Pod

DaemonSet 全節點常駐服務

由 K8s 的 DaemonSet Controller 管理,確保 Cluster 中每一個(或符合特定條件的)Node 上,都剛好運行一個 Pod copy。每當有新 Node 加入 Cluster 時,Pod 會自動在該 Node 上被建立;當 Node 被移除時,該 Pod 也會自動被垃圾回收(Garbage Collected)。

  • 常見應用場景:
    • 網路外掛(CNI):如 Calico、Weave Net 或 Flannel(需在每台 Node 上處理網路封包轉發與跨節點 Tunnel)。
    • 網路代理(Network Proxy):如 kube-proxy,在每個 Node 上維護網路規則。
    • 日誌收集 Agent:如 Fluentd、Logstash。
    • 節點監控 Agent:如 Prometheus Node Exporter、自訂的 Monitoring Agent。

DaemonSet 運作機制與演進

在 Kubernetes 早期的版本(v1.12 以前),DaemonSet 是由 DaemonSet Controller 直接將 Pod 的 spec.nodeName 欄位填上特定 Node 名稱來指定節點;從 v1.12 版本開始,DaemonSet 正式全面改由預設調度器(Default Scheduler)配合 NodeAffinity 來實現。

即便 Node 被加上 NoSchedule 污點(例如 Control Plane 節點),只要 DaemonSet Pod 帶有對應的 Toleration(容忍度),就能順利部署到控制面節點上。

DaemonSet 定義與常用檢視指令

DaemonSet 的 YAML 寫法與 ReplicaSet 極為相似,主要差異在於 kind 指定為 DaemonSet,且不需要聲明 replicas(因為數量由 Node 的數量決定)。

💡 後面會說明ReplicaSet

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      tolerations:
      - operator: Exists # 容忍所有污點,確保控制面與工作節點都能部署
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.3.1
        ports:
        - containerPort: 9100
          hostPort: 9100 # 綁定 Node 主機連接埠

  • 常用管理指令:

查詢 DaemonSet:

kubectl get daemonsets -n kube-system

查看詳細狀態(包含 desired、current、ready 數量與 Pod Template):

kubectl describe daemonsets node-exporter -n kube-system


Static Pods 由 Kubelet 直接管理的 Pods

通常 Pod 的建立流程都需要經過 API Server -> etcd -> Scheduler -> Kubelet 的完整控制流程。但有一個典型的「雞生蛋、蛋生雞」難題:當控制面(Control Plane)本身還沒建立起來、API Server 與 etcd 都尚未存在時,我們要如何把控制面的組件當作容器跑起來?

答案就是 Static Pods(靜態 Pod)!

Static Pod 的特點與配置方法

  1. 完全由 Kubelet 獨立管理 (記得我們的廠長!):Kubelet 啟動時會讀取本機配置。只要將定義檔(YAML)放入特定目錄,Kubelet 就會透過 Container Runtime(如 containerd、CRI-O)直接啟動並維護該 Pod。
  2. 自動同步與自我修復:Kubelet 會定期掃描該目錄。若目錄下新增或更新了 YAML 檔,Kubelet 會自動建立或更新 Pod;若將 YAML 檔案刪除,Kubelet 會自動停止並移除該 Pod。
  3. 完全無視 Scheduler:繞過Control Plane與調度器,即使 API Server 停擺,只要 Kubelet 正常運作,靜態 Pod 就會持續運行。
  4. 刪除與修改限制:無法透過 kubectl delete pod 刪除(即使強行刪除,Kubelet 發現本機 YAML 依然存在,就會立即重建 Pod)。唯一修改或刪除的方式是直接登入該 Node,修改或移除目錄中的 YAML 檔案。

如何指定 Static Pods 目錄?

Kubelet 提供了兩種方式來設定Static Pod 的 Manifest 檔案目錄路徑:

  1. 透過 Kubelet 啟動參數:
    在 kubelet.service 的啟動命令中加入 --pod-manifest-path=/etc/kubernetes/manifests。
  2. 透過 Kubelet 設定檔:
    在 kubeconfig.yaml 或 config.yaml 中設定 staticPodPath: /etc/kubernetes/manifests。

當 Control Plane 出現故障時,無法使用 kubectl 查詢 Pod 狀態,此時可以透過 Container Runtime 工具(如 crictl ps、nerdctl ps 或 docker ps)在 Node 主機上記錄與除錯。

映象 Pod (Mirror Pod) 機制

雖然 Static Pods 繞過了 API Server,但為了讓管理者依然能透過 kubectl get pods 看到這些控制面 Pod,Kubelet 會在與 API Server 連線建立後,主動在 API Server 上建立一個唯讀的 Mirror Pod。

  • Mirror Pod 的名稱通常會在最後加上 Node 的主機名稱(例如 kube-apiserver-node01)。
  • 在 API Server 端看見的 Mirror Pod 僅供唯讀狀態展示,無法透過 kubectl 進行編輯或刪除。

kubeadm 叢集自我啟動(Bootstrapping)範例

使用 kubeadm 初始化 K8s 叢集時,kube-apiserver、kube-controller-manager、kube-scheduler 與 etcd 就是以 Static Pods 的形式部署在 Control Plane 節點上:

# 登入 Control Plane 節點查看靜態 Pod 配置目錄
ls -la /etc/kubernetes/manifests/

# 輸出結果:
# etcd.yaml
# kube-apiserver.yaml
# kube-controller-manager.yaml
# kube-scheduler.yaml

只要執行 kubectl get pods -n kube-system,就能看到這些由 Kubelet 建立 Mirror Pod 並註冊到控制面的組件。


比較:Static Pods vs. DaemonSet

項目 Static Pods DaemonSet
由誰控管 該節點上的 kubelet Control Plane 的 DaemonSet Controller
建立機制 掃描 Node 本機 /etc/kubernetes/manifests/ 目錄直接建立 透過 API Server 配合 Default Scheduler 與 NodeAffinity/Tolerations
主要用途 部署 Control Plane 核心組件(etcd, apiserver 等) 部署全叢集基礎設施 Agent(CNI, kube-proxy, 日誌, 監控)
刪除/修改方式 直接修改/移除 Node 本機的 YAML 檔案 透過 API Server 指令(kubectl delete/edit ds)
檢視工具 Node 端使用 crictl ps,Cluster 端看 Mirror Pod 直接使用 kubectl 進行叢集級別管理

總結

  • 本篇總結:
    DaemonSet 適合部署基礎設施 Agent(由 API Server 與 Controller 統一管理);而 Static Pods 則繞過控制面,由本機 Kubelet 直接監視目錄運行,常用於部署 K8s 控制面自身的基礎組件。
  • 下一篇預告:
    掌握了各式 Pod 的部署型態後,明天 Day 10 我們將學習 應用程式升級策略與無縫回滾——實作 Deployment 的 RollingUpdate 與 Recreate 機制,並示範如何用 kubectl rollout undo 在幾秒內快速復原失敗的版次!敬請期待!

Takeaway

  • DaemonSet 全節點部署:確保叢集中每個(或指定條件的)Worker Node 上都剛好運行一個 Pod copy,常用於 kube-proxy、CNI 網路元件、日誌收集與節點監控。
  • DaemonSet 派發機制演進:自 v1.12 起,DaemonSet 正式採用 Default Scheduler 結合 NodeAffinity 進行 Pod 的統一調度。
  • Static Pods 去中心化管理:不透過 API Server 或 Scheduler,由當地的 Kubelet 掃描 /etc/kubernetes/manifests/ 目錄下的 YAML 檔直接啟動與維護。
  • Static Pods 的修改與刪除:無法透過 kubectl delete pod 刪除,只能直接移除或修改 Node 當地目錄內的 YAML 檔案;在 API Server 看到的僅為唯讀的 Mirror Pod。
  • K8s 自我啟動(Bootstrapping)原理:kubeadm 建立叢集時,kube-apiserver、etcd 等控制面關鍵組件就是以 Static Pods 的形式運行。

上一篇
Day 08:【資源】 容器資源限制與配額管理 (Limits & Quotas)
下一篇
Day 10:【系統】 應用程式升級策略與無縫回滾 (Deployment Rolling Update & Rollback)
系列文
Kubernetes學習心得分享 共 12 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言